package resource

import (
	reqContext "context"

	"git.cloud.inspur.com/ichain/ichain-protos-go/common"
	ab "git.cloud.inspur.com/ichain/ichain-protos-go/consenser"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/errors/retry"
	contextImpl "git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain/context"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain/transactor"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/ichain"
	ccomm "git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/util/comm"
	"github.com/pkg/errors"
)

// retrieveBlock 接收区块
func retrieveBlock(reqCtx reqContext.Context, consensers []ichain.Consenser, chain string, pos *ab.SeekPosition, opts options) (*common.Block, error) {
	ctx, ok := contextImpl.RequestClientContext(reqCtx)
	if !ok {
		return nil, errors.New("failed get client context from reqContext for signPayload")
	}

	hash, err := ccomm.TLSCertHash(ctx.CryptoSuite(), ctx.EndpointConfig())
	if err != nil {
		return nil, errors.Wrapf(err, "failed to get tls cert hash")
	}

	chainHeaderOpts := ichain.ChainHeaderOpts{
		TLSCertHash: hash,
	}

	tx := transactor.NewTransactor(reqCtx, chain)

	seekInfo := &ab.SeekInfo{
		Start:    pos,
		Stop:     pos,
		Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
	}

	payload, err := tx.CreatePayload(common.HeaderType_DELIVER_SEEK_INFO, chainHeaderOpts, seekInfo)
	if err != nil {
		return nil, errors.WithMessage(err, "create payload fail")
	}

	resp, err := retry.NewInvoker(retry.New(opts.retry)).Invoke(
		func() (interface{}, error) {
			return tx.SendPayload(payload, consensers)
		},
	)
	if err != nil {
		return nil, err
	}
	return resp.(*common.Block), err
}

func newNewestSeekPosition() *ab.SeekPosition {
	return &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
}

func newSpecificSeekPosition(index uint64) *ab.SeekPosition {
	return &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: index}}}
}
